import { cartographicFromMercator } from './Utils/transform';
import MapApp from './MapApp';
import VGE from '../../VGE';

export class Camera {
	constructor(viewer) {
		this.viewer = viewer;
	}

	/**
	 * 查询视角参数
	 * @param original
	 * @returns {Promise<{original: boolean, heading: *|{getFreeCameraOptions}, lon: *, pitch: *, lat: *, height: *}>}
	 */
	async getCameraParams(original = true) {
		try {
			const map = this.viewer;
			if (!map.getFreeCameraOptions) return;
			const {
				position: { x, y, z }
			} = map.getFreeCameraOptions();
			const position = cartographicFromMercator(x, y, z);
			const pitch = +map.getPitch();
			const bearing = +map.getBearing();

			const result = {
				lon: position.longitude,
				lat: position.latitude,
				height: position.height,
				pitch: pitch,
				heading: bearing
			};

			if (!original) {
				result.heading = bearing < 0 ? -bearing : 360 - bearing;
				result.original = 'VGE-CAMERA';
			}

			return result;
		} catch (e) {
			console.error(e.message);
		}
	}

	/**
	 * 飞到给定视角
	 * @param cameraParams
	 * @param duration
	 * @returns {Promise<void>}
	 */
	async flyTo(cameraParams, duration = 1) {
		if (!VGE.util.validateCameraParams(cameraParams)) return;
		try {
			const map = this.viewer;
			let { lon, lat, height: x, heading, pitch } = cameraParams;

			if (cameraParams.original === 'VGE-CAMERA') {
				heading = (360 - heading) % 360;
				// pitch = pitch - 90
			}

			const cam = {
				center: [lon, lat],
				bearing: heading,
				pitch: pitch,
				zoom: Math.max(8.15, 26.018 - Math.log(x) * 1.443),
				duration: +duration * 1000
			};

			map.flyTo(cam);
		} catch (e) {
			console.error(e.message);
		}
	}

	/**
	 * 主视角
	 * @returns {Promise<void>}
	 */
	async homeView() {
		this.flyTo(MapApp.homeViewParams);
	}

	async zoomIn(factor = -1, duration = 1) {
		try {
			factor =
				factor !== -1 ? factor : this.viewer.getZoom() + 1 >= 24 ? 24 : this.viewer.getZoom() + 1;
			this.viewer.zoomTo(factor, { duration: duration * 1000 });
		} catch (e) {
			console.error(e.message);
		}
	}

	async zoomOut(factor = -1, duration = 1) {
		try {
			factor =
				factor !== -1 ? factor : this.viewer.getZoom() - 1 <= 0 ? 0 : this.viewer.getZoom() - 1;
			this.viewer.zoomTo(factor, { duration: duration * 1000 });
		} catch (e) {
			console.error(e.message);
		}
	}
}
